#ifndef _DATA_MAMANAGER_H_
#define _DATA_MAMANAGER_H_

#include "Resource.h"
#include "ResourceManager.h"
#include "Singleton.h"
#include "String.h"
#include "Database/Field.h"


//定义默认的数据载入XML文件
#define DM_DB_DEFINE_FILE     "../scripts_xml/datadefine.xml"
#define DM_DB_DATA_FILE       "../scripts_xml/database.xml"

class Database;

class  SERVER_DECL DataManager:public Singleton<DataManager>
{

public:
	enum  DataType
	{
		DataTypeNone		= 	0,	//无效数据类型
		DataTypeUInt32		= 	1,	//32位无符号整形
		DataTypeInt32		=	2,	//32位整形
		DataTypeFloat		=	3,	//32位浮点
		DataTypeDouble		=	4,	//64位浮点
		DataTypeUInt64		=	5,	//64位无符号整形
		DataTypeInt64		=	6,	//64位整形
		DataTypeString		=	7	//字符串类型
	};

	enum  DatabaseType
	{
		DatabaseTypeNone	= 	0,	//无效数据库类型
		DatabaseTypeCenter	=	1,	//数据交换中心数据库
		DatabaseTypeAccount	=	2,	//账号数据库
		DatabaseTypeCharacter	=	3,	//角色物品数据库
		DatabaseTypeServer	=	4,	//服务器运行数据库
		DatabaseTypeLogs	= 	5,	//游戏日志数据库
		DatabaseTypeGateway	=	6,	//网关数据库
		DatabaseTypeInfo	=	7,	//信息日志数据库
		DatabaseTypeCustom	=	50	//用户自定义数据库
	};

	//数据库字段结构定义
	typedef struct field_def_tag_
	{
	    DataType	 data_type;           //数据类型
	    String	 data_name;	      //字段名称
	    uint16	 offset; 	      //偏移位置
	    String 	 comment;	      //字段注释
	}field_def;

	typedef std::vector<field_def>		FieldDefVector;

	//数据表结构定义
	typedef struct table_def_tag_
	{
		String		table_name;	//表名称
		String		comment;	//表注释
		uint16		value_size;	//数据表值空间大小
		uint16		string_size;	//数据表字符串类型数量
		std::set<int16>	primaries; 	//多主键偏移存放
		int16		primary;	//单主键偏移位置

		FieldDefVector	fields;		//表字段定义集合

		String		db_name;	//表的数据库名称
		Database  *     db_connect;     //数据库连接对象

	}table_def;

	typedef  std::map<String,table_def*>			TableDefSet;
	typedef  std::map<uint16,table_def *>			ReourceTypeTableDefSet;
	typedef  std::map<uint16,String>			ReourceTypeTableNameSet;


	//数据库结构定义
	typedef struct database_def_tag_
	{
		uint16		db_type;		//数据库类型
		String		db_name;		//数据库名称
		String		comment;		//数据库注释
		TableDefSet	tables;			//数据库表定义集合

		Database * 	db_connect;		//数据库连接对象
	}database_def;


	typedef  std::map<String,database_def *>		DatabaseDefSet;
	typedef  std::map<uint16,database_def *>		DatabaseTypeSet;
public:
	DataManager();
	~DataManager();
	
	bool    Startup(const uint32 & group_id,const String & define_fileName = DM_DB_DEFINE_FILE, const String & data_fileName = DM_DB_DATA_FILE);
        void    Shutdown(void);

	void	clearAll(void);


	//注册ResourceManager 字段索引
	bool	registerResoruceManagerFieldIndex(const uint16 & resType,ResourceManager * resMgr);

	//获取资源对象数据库连接
	Database *  getDatabaseConnecting(const uint16 & resType);
	Database *  getDatabaseConnecting(const DatabaseType & dbType);

	//根据资源类型获取数据表名
	const String getResourceTypeTableName(const uint16 & resType);

	//根据资源类型得到数据库表定义
	table_def * getResourceTypeTableDef(const uint16 & resType);

	//资源对象保留存储空间
	bool ResourceReserveBuffer(Resource * res);	
	//获取资源对象Load SQL字符串
	const String getResourceLoadSQLString(const uint16 & resType);
	
	//Fetch Resource database
	bool resourceFetchDB(Resource * res,Field * fields);
	//upate Resource sql string
	const String getResourceUpdateSQLString(Resource * res, const std::vector<bool> & valueflags,const std::vector<bool> & stringflags);
	
	//insert Resource SQL string
	const String getResourceInsertSQLString(Resource * res);

	//直接对数据表操作
	bool initData(const DatabaseType & db_type,const String & table_name,Fields * fields);
        bool updateData(const DatabaseType & db_type,const String & table_name,Fields * fields);	
        bool updateDataQuery(const DatabaseType & db_type,const String & table_name,Fields * fields,const char * QueryString,...);
	bool insertData(const DatabaseType & db_type,const String & table_name,Fields * fields);
	bool getDatas(const DatabaseType & db_type,const String & table_name,FieldRows * fieldRows,const char * QueryString,...);
	
	//指定表，和字段进行查询，返回数据为指定的字段  fieldLists 格式为逗号分隔 "fieldName1,fieldName2....fieldNameX"
	bool queryDatas(const DatabaseType & db_type,const String & table_name,FieldRows * fieldRows,const String & fieldLists, const char * QueryString,...);	
        
	//操作数据 成功返回影响的行数 失败返回 -1
	int updateDataAffected(const DatabaseType & db_type,const String & table_name,Fields * fields);	
        int updateDataQueryAffected(const DatabaseType & db_type,const String & table_name,Fields * fields,const char * QueryString,...);
protected:

	bool	loadDataDefineXMLFile();
	bool    loadDataXMLFile();


	//数据库结构定义
	DatabaseDefSet		m_databases;
	DatabaseTypeSet		m_databaseTypes;
	//所有表结构定义
	TableDefSet		m_tables;
	//资源类型对应的表结构对象
	ReourceTypeTableDefSet		m_resourceTypeTables;
	//资源类型对应表名称对象
	ReourceTypeTableNameSet		m_resourceTypeTableNames;

	String	m_dataDefileFileName;
	String	m_dataFileName;
	uint32 	m_group_id;

};




#define   sDataMgr     DataManager::getSingleton()

#endif
